home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / dsp / dspgroup / asms.arc / MODEM.ASM < prev    next >
Encoding:
Assembly Source File  |  1987-11-26  |  16.3 KB  |  692 lines

  1. ;  AMSAT/TAPR DSP BPSK to BEL-202 translator for JAS and for use with
  2. ;       TAPR/JAS modem.   Sample rate should be set to 9600 samples/sec. 
  3. ;          code by Bob McGwier N4HY with many suggestions by
  4. ;                       W3IWI Tom Clark included
  5. ;
  6. ; Needs: post frequency synthesis filtering and adaptive equalization
  7. ;        to achieve "perfection" :-)
  8.      org 0
  9.      b go
  10.      org 0FF0H
  11.      dw 2731  ; 1600Hz
  12.      dw 2048  ; 1200 Hz
  13.      dw 3755  ; 2200 Hz
  14. ;
  15. ;      Okay Jose' set up equates for data memory etc.
  16. ;
  17.         org 10H  ;  code should begin at memory address 16 cause David
  18.            ;  does something strange with locations 0-15.  Does
  19.            ;  he in fact document this?
  20.     
  21. sine:   equ 0    ;  will store sine values from tone
  22. one:    equ 1      ;  guess what goes here duhhhhh!
  23. freq:   equ 2    ;  PLL frequency stored here
  24. phase:  equ 3    ;  PLL phase stored here
  25. maskl:  equ 4    ;  mask for fine or low order bits of phase
  26. mask:   equ 5    ;  mask for doing modulo 16384 arithmetic with phase
  27. sinx:   equ 6    ;  used to store coarse sine value (high order bits)
  28. cosx:   equ 7    ;  as above for cosine
  29. mone:   equ 8    ;   minus one stored here
  30. wkph:   equ 9    ;  different phases (PLL, remodulator tone etc) are stored hr
  31.                  ;  for frequency synthesis
  32. masko:  equ 10   ;  mask for converting on board PCM to DAC format
  33. mps:    equ 11   ;  multiplier for quadrant determination for sine
  34. mpc:    equ 12   ;  multiplier for quadrant determination for cosine
  35. siny:   equ 13   ;  fine correction value for use in SIN(X+Y) = sinx*cosy+
  36. cosy:   equ 14   ;          cosx*siny
  37. cosine: equ 15   ;  cosine is also needed for Q arm in Costas loop
  38. coph:   equ 16   ;  working number holder
  39. modem:  equ 17   ;  Used to choose between complex tone for arms and real tone
  40.                  ;  in the modulator as explained below
  41. freql:  equ 18   ;  low tone for remodulator stored here
  42. freqh:  equ 19   ;  high tone remod.
  43. freqo:  equ 20   ;  freqo is assigned one of the values above for remod
  44. phaseo: equ 71      ;  phaseo is the phase of the remodulator output. phase is
  45.            ;  as continuous as DSP will allow on this board
  46. xn0:    equ 21   ;  place  for storing all the values for the "I" or data arm
  47. xn1:    equ 22
  48. xn2:    equ 23
  49. xn3:    equ 24
  50. xn4:    equ 25
  51. xn5:    equ 26
  52. xn6:    equ 27
  53. xn7:    equ 28
  54. xn8:    equ 29
  55. xn9:    equ 30
  56. xn10:   equ 31
  57. xn11:   equ 32
  58. xn12:   equ 33
  59. xn13:   equ 34
  60. xn14:   equ 35
  61. xn15:   equ 36
  62. xn16:   equ 37
  63. xn17:   equ 38
  64. xn18:   equ 39
  65. xn19:   equ 40
  66. xn20:   equ 41
  67. xn21:   equ 42
  68. xn22:   equ 43
  69. xn23:   equ 44
  70. yn0:    equ 45  ; storage for values in "Q" or phase error arm.
  71. yn1:    equ 46
  72. yn2:    equ 47
  73. yn3:    equ 48
  74. yn4:    equ 49
  75. yn5:    equ 50
  76. yn6:    equ 51
  77. yn7:    equ 52
  78. yn8:    equ 53
  79. yn9:    equ 54
  80. yn10:   equ 55
  81. yn11:   equ 56
  82. yn12:   equ 57
  83. yn13:   equ 58
  84. yn14:   equ 59
  85. yn15:   equ 60
  86. yn16:   equ 61
  87. yn17:   equ 62
  88. yn18:   equ 63
  89. yn19:   equ 64
  90. yn20:   equ 65
  91. yn21:   equ 66
  92. yn22:   equ 67
  93. yn23:   equ 68
  94. c0:     equ 69  ; Phase error
  95. maskf:  equ 70  ; frequency mask so that frequency doesn't try and leave
  96.                 ; proper range
  97. tester: equ 72  ;  remodulator output   -300 to 300 millivolts on DAC's
  98. H10:    equ 73  ;  arm filter value too large to use mpyk
  99. H11:    equ 74  ;  arm filter value too large to use mpyk
  100. sweep:  equ 75  ;  contains sweep value  +/- one frequency unit per sample
  101. highfq: equ 76  ;  high end of sweep range
  102. lowfq:  equ 77  ;  low end of sweep range
  103. sintbl: dw      0  ; coarse sine table in steps of PI/64 radians to PI/2
  104.        dw    804
  105.        dw   1607
  106.        dw   2410
  107.        dw   3211
  108.        dw   4011
  109.        dw   4807
  110.        dw   5601
  111.        dw   6392
  112.        dw   7179
  113.        dw   7961
  114.        dw   8739
  115.        dw   9511
  116.        dw  10278
  117.        dw  11038
  118.        dw  11792
  119.        dw  12539
  120.        dw  13278
  121.        dw  14009
  122.        dw  14732
  123.        dw  15446
  124.        dw  16150
  125.        dw  16845
  126.        dw  17530
  127.        dw  18204
  128.        dw  18867
  129.        dw  19519
  130.        dw  20159
  131.        dw  20787
  132.        dw  21402
  133.        dw  22004
  134.        dw  22594
  135.        dw  23169
  136.        dw  23731
  137.        dw  24278
  138.        dw  24811
  139.        dw  25329
  140.        dw  25831
  141.        dw  26318
  142.        dw  26789
  143.        dw  27244
  144.        dw  27683
  145.        dw  28105
  146.        dw  28510
  147.        dw  28897
  148.        dw  29268
  149.        dw  29621
  150.        dw  29955
  151.        dw  30272
  152.        dw  30571
  153.        dw  30851
  154.        dw  31113
  155.        dw  31356
  156.        dw  31580
  157.        dw  31785
  158.        dw  31970
  159.        dw  32137
  160.        dw  32284
  161.        dw  32412
  162.        dw  32520
  163.        dw  32609
  164.        dw  32678
  165.        dw  32727
  166.        dw  32757
  167.        dw  32767  ; PI/2
  168. fines: dw      0  ; fine sine table  in steps of PI/(64*64) radians to PI/64
  169.        dw     12
  170.        dw     25
  171.        dw     37
  172.        dw     50
  173.        dw     62
  174.        dw     75
  175.        dw     87
  176.        dw    100
  177.        dw    113
  178.        dw    125
  179.        dw    138
  180.        dw    150
  181.        dw    163
  182.        dw    175
  183.        dw    188
  184.        dw    201
  185.        dw    213
  186.        dw    226
  187.        dw    238
  188.        dw    251
  189.        dw    263
  190.        dw    276
  191.        dw    289
  192.        dw    301
  193.        dw    314
  194.        dw    326
  195.        dw    339
  196.        dw    351
  197.        dw    364
  198.        dw    376
  199.        dw    389
  200.        dw    402
  201.        dw    414
  202.        dw    427
  203.        dw    439
  204.        dw    452
  205.        dw    464
  206.        dw    477
  207.        dw    490
  208.        dw    502
  209.        dw    515
  210.        dw    527
  211.        dw    540
  212.        dw    552
  213.        dw    565
  214.        dw    578
  215.        dw    590
  216.        dw    603
  217.        dw    615
  218.        dw    628
  219.        dw    640
  220.        dw    653
  221.        dw    665
  222.        dw    678
  223.        dw    691
  224.        dw    703
  225.        dw    716
  226.        dw    728
  227.        dw    741
  228.        dw    753
  229.        dw    766
  230.        dw    779
  231.        dw    791
  232. finec: dw   32767  ;ditto to above for fine sine
  233.        dw   32766
  234.        dw   32766
  235.        dw   32766
  236.        dw   32766
  237.        dw   32766
  238.        dw   32766
  239.        dw   32766
  240.        dw   32766
  241.        dw   32766
  242.        dw   32766
  243.        dw   32766
  244.        dw   32766
  245.        dw   32766
  246.        dw   32766
  247.        dw   32766
  248.        dw   32766
  249.        dw   32766
  250.        dw   32766
  251.        dw   32766
  252.        dw   32766
  253.        dw   32765
  254.        dw   32765
  255.        dw   32765
  256.        dw   32765
  257.        dw   32765
  258.        dw   32765
  259.        dw   32765
  260.        dw   32765
  261.        dw   32764
  262.        dw   32764
  263.        dw   32764
  264.        dw   32764
  265.        dw   32764
  266.        dw   32764
  267.        dw   32764
  268.        dw   32763
  269.        dw   32763
  270.        dw   32763
  271.        dw   32763
  272.        dw   32763
  273.        dw   32762
  274.        dw   32762
  275.        dw   32762
  276.        dw   32762
  277.        dw   32762
  278.        dw   32761
  279.        dw   32761
  280.        dw   32761
  281.        dw   32761
  282.        dw   32760
  283.        dw   32760
  284.        dw   32760
  285.        dw   32760
  286.        dw   32759
  287.        dw   32759
  288.        dw   32759
  289.        dw   32759
  290.        dw   32758
  291.        dw   32758
  292.        dw   32758
  293.        dw   32758
  294.        dw   32757
  295.        dw   32757
  296. armfilt: dw  6851   ; H10 above
  297.          dw   10195   ; H11 above
  298. go:  ldpk 0         ; make sure that we are pointing to 0 data page
  299.      larp ar0
  300.      lark ar0,4
  301.      lack one   ; make and store one
  302.      sacl one
  303.      lack armfilt ; store address of the too large coefficients
  304.      tblr H10
  305.      add one
  306.      tblr H11
  307.      lac one,11  ; make and store DAC converter mask
  308.      sacl masko
  309.      lac one,13   ; make and store frequency mask
  310.      sub one
  311.      sacl maskf
  312.      lt one
  313.      mpyk 3243  ; make and store 1900 Hz as high end of sweep range
  314.      pac
  315.      sacl highfq
  316.      lt one
  317.      mpyk 2218 ; make and store 1300 Hz as low end of sweep range
  318.      pac
  319.      sacl lowfq
  320.      zac
  321.      sub one
  322.      sacl mone  ; make and store minus one
  323.      lac one,14
  324.      sub one
  325.      sacl mask  ; make and store mask for modulo 16384 phase arithmetic
  326.      lac one,6
  327.      sub one
  328.      sacl maskl ; make and store fine part of address mask;
  329.      zac
  330.      sacl phase
  331.      lac one,8     ; make and store frequency address in memory
  332.      sub one
  333.      sacl freq
  334.      lac freq,4
  335.      tblr freq       ; read PLL initial frequency
  336.      add one
  337.      tblr freql      ; read low FSK tone
  338.      add one
  339.      tblr freqh     ; read high FSK tone
  340.      lac one
  341.      sacl sweep
  342.      
  343. ;  Okay the BS is over lets get to work !     
  344.      
  345. wait: bioz fire    ; is it time for a new sample     
  346.       b wait       ; nope go wait in the corner
  347. fire: in xn0,pa3   ; get a new sample here
  348.                ; as the following routines have a variable length
  349.      lac xn0,4
  350.      sub one,15   ; Change ADC format to two's complement
  351.      sacl xn0
  352.  
  353. ;     remodulator output
  354.  
  355.      lac tester,6
  356.      addh masko
  357.      sach yn0
  358.      out yn0,pa4   ; send it to the TNC
  359.  
  360. ;     end output
  361.  
  362. ;     Now begin demodulator
  363.      lack one
  364.      sacl modem  ; store control that makes complex tone
  365.      lack one  ;
  366.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  367.      sacl mpc  ;
  368.      lac phase
  369.      call tones ; go make complex tone
  370.  
  371.      lt xn0  ; load the current sample
  372.      mpy cosine; multiply by cosine
  373.      pac
  374.      sach yn0,1 ; store it Q channel current sample
  375.      mpy sine ; multiply sample by sine
  376.      pac
  377.      sach xn0,1 ; now store it in current sample place for I channel
  378.      
  379. ;     Low pass for each sample cutoff is at 1200 Hz. Carrier is 20-25 dB down
  380.  
  381. ;     First lowpass I arm product
  382.  
  383.      zac
  384. ;
  385.      lt xn23
  386.      mpyk -319
  387. ;
  388.      ltd xn22
  389.      mpyk -561
  390. ;
  391.      ltd xn21
  392.      mpyk -110  
  393. ;
  394.      ltd xn20
  395.      mpyk 459
  396. ;
  397.      ltd xn19
  398.      mpyk 964
  399. ;
  400.      ltd xn18
  401.      mpyk 409
  402. ;
  403.      ltd xn17
  404.      mpyk -938
  405. ;
  406.      ltd xn16
  407.      mpyk -2028
  408. ;
  409.      ltd xn15
  410.      mpyk -1163
  411. ;
  412.      ltd xn14
  413.      mpyk 2206
  414. ;
  415.      ltd xn13
  416.      mpy H10
  417. ;
  418.      ltd xn12
  419.      mpy H11
  420. ;
  421.      ltd xn11
  422.      mpy H11
  423. ;
  424.      ltd xn10
  425.      mpy H10
  426. ;
  427.      ltd xn9
  428.      mpyk 2206
  429. ;
  430.      ltd xn8
  431.      mpyk -1163
  432. ;
  433.      ltd xn7
  434.      mpyk -2028
  435. ;
  436.      ltd xn6
  437.      mpyk -938
  438. ;
  439.      ltd xn5
  440.      mpyk 409
  441. ;
  442.      ltd xn4
  443.      mpyk 964
  444. ;
  445.      ltd xn3
  446.      mpyk 459
  447. ;
  448.      ltd xn2
  449.      mpyk -110
  450. ;
  451.      ltd xn1
  452.      mpyk -561
  453. ;
  454.      ltd xn0
  455.      mpyk -319
  456. ;
  457.      apac
  458. ;
  459.      sach xn0,1
  460.      
  461. ;  Now do the Q arm
  462.  
  463.      zac
  464. ;
  465.      lt yn23
  466.      mpyk -319
  467. ;
  468.      ltd yn22
  469.      mpyk -561
  470. ;
  471.      ltd yn21
  472.      mpyk -110  
  473. ;
  474.      ltd yn20
  475.      mpyk 459
  476. ;
  477.      ltd yn19
  478.      mpyk 964
  479. ;
  480.      ltd yn18
  481.      mpyk 409
  482. ;
  483.      ltd yn17
  484.      mpyk -938
  485. ;
  486.      ltd yn16
  487.      mpyk -2028
  488. ;
  489.      ltd yn15
  490.      mpyk -1163
  491. ;
  492.      ltd yn14
  493.      mpyk 2206
  494. ;
  495.      ltd yn13
  496.      mpy H10
  497. ;
  498.      ltd yn12
  499.      mpy H11
  500. ;
  501.      ltd yn11
  502.      mpy H11
  503. ;
  504.      ltd yn10
  505.      mpy H10
  506. ;
  507.      ltd yn9
  508.      mpyk 2206
  509. ;
  510.      ltd yn8
  511.      mpyk -1163
  512. ;
  513.      ltd yn7
  514.      mpyk -2028
  515. ;
  516.      ltd yn6
  517.      mpyk -938
  518. ;
  519.      ltd yn5
  520.      mpyk 409
  521. ;
  522.      ltd yn4
  523.      mpyk 964
  524. ;
  525.      ltd yn3
  526.      mpyk 459
  527. ;
  528.      ltd yn2
  529.      mpyk -110
  530. ;
  531.      ltd yn1
  532.      mpyk -561
  533. ;
  534.      ltd yn0
  535.      mpyk -319
  536. ;
  537.      apac
  538. ;
  539.      sach yn0,1
  540. ;  Okay we now have filtered products with data bauding pseudo base banded
  541. ;  Let's close the loop and lock on
  542.      lac xn0;  Hard limit data line for phase error detector
  543.      bgez pdps  ; is data baud a plus one ?
  544.      lac freql  ;  Nope, store 1200 Hz in output frequency
  545.      sacl freqo
  546.      lt yn0     ; get ready for a multiply
  547.      mpyk -1    ; multiply phase error arm by -1
  548.      pac
  549.      b ny       ; go close the loop
  550. pdps: lac freqh  ; Yes it was plus one
  551.      sacl freqo ; so store high 2200Hz tone in output frequency
  552.      lac yn0
  553. ny:  sacl c0   ; store sign corrected phase error.
  554.      lac c0,7    ; multiply phase error by 0.001 for frequency gain
  555.               ; Both of these values for gains were determined by
  556.               ; experiment and seem  to be the best compromise for
  557.               ; stability and fast lock up.
  558.  
  559. ; error updates are computed compute new phase and freq
  560.  
  561.      sach cosy   ; store freq update
  562.      lac freq    ; load frequency
  563.      add cosy    ; add update
  564.      and maskf   ; can't let the frequency go to hades in a jet airplane
  565.      sacl freq   ; store it for next PLL step.
  566.      lac c0,13 ; make phase gain 1/4 of phase error
  567.      sach cosy ;
  568.      lac cosy  ;
  569.      bgez delph  ; is phase error nonnegative?
  570.      add one,15  ;  No so bring it back from -angle to between 0 & 2*PI
  571. delph: add phase   ; add the old phase 
  572.      add freq    ; add the phase increment (frequency)
  573.      and mask    ; modulo 2*pi
  574.      sacl phase  ; store it for next sample complex tone generation step
  575.      lac freq  ;
  576.      sub lowfq    ; did above correction make the frequency go out the bottom?
  577.      bgz outt    ; no
  578.      lac highfq  
  579.      sacl freq  ; force frequency back to top of region
  580. outt: lac mone
  581.      sacl modem ; tell tone that we want a real sinusoid
  582.      lack one
  583.      sacl mps  ;   Restore sine and cosine quadrant multipliers
  584.      sacl mpc  ;
  585.      lac phaseo; load current output phase
  586.      add freqo ; add current frequency
  587.      and mask ; do mod 16384 arithmetic
  588.      sacl phaseo; store phase
  589.      call tones; go make tone
  590.      lac sine
  591.      sacl tester ; store the output tone value here
  592.      b wait         ; go output and then do it again
  593.  
  594. ;     complex tone generator if modem>0 if modem<0 sine wave generator
  595.  
  596. tones: sacl wkph  ;  store a working copy
  597.      lac wkph,4
  598.      subh one
  599.      blz getem  ;  is it in a quadrant bigger than first?
  600.      subh one
  601.      bgez thfr; is it in a quadrant greater than two?
  602.      lac 1,13  ;  nope so load pi
  603.      sub wkph  ;  subtract phase so that it maps back into 1st quad
  604.      sacl wkph ; store
  605.      lac mone  ; load -1
  606.      sacl mpc  ; store it in the cosine multiplier
  607.      b getem   ; go read tables
  608. thfr: lac mone  ; multiplier for bottom half
  609.      sacl mps  ; store
  610.      lac wkph  ; 
  611.      sub one,13 ; map angle back to  upper half and go do it again
  612.      b tones
  613. getem: lac wkph,10 ; take 1st quadrant phase equiv for sine and pick 
  614.                    ; off coarse part of phase address
  615.      sach coph     ; store it
  616.      lack sintbl   ;  load sine table offset into accumulator
  617.      add coph      ; add coarse address off set
  618.      tblr sinx     ; read the coarse sine value
  619.      lac one,6     ;  load pi/2
  620.      sub coph      ; subtract the coarse phase to get cosines offset
  621.      sacl coph      
  622.      lack sintbl
  623.      add coph      ; do same as above for coarse cosine
  624.      tblr cosx
  625.      lac wkph      ; load working phase
  626.      and maskl     ;  mask off fine addres
  627.      sacl coph     ; store it
  628.      lack fines    ; locate fine table offset
  629.      add coph      ; add for offset into fine table
  630.      tblr siny     ;  read table
  631.      lack finec
  632.      add coph
  633.      tblr cosy
  634.      zac
  635.      lt sinx       ; load sinx
  636.      mpy cosy      ;  multiply by cosy
  637.      lta siny      ; load t reg with fine sin and accumulate previous prod.
  638.      mpy cosx      ; multiply by coarse cosx to use sin(X+Y)
  639.      apac          ; add the result to coarse sine
  640.      sach sine     ; store it.
  641.      lac modem 
  642.      blz mult
  643.      lac 1,12      ; load full address pi/2
  644.      sub wkph      ; subtract the working phase to get cosine
  645.      sacl wkph 
  646.      lac wkph,10   ;  from here to the later MARK it is identical to above
  647.      sach coph
  648.      lack sintbl
  649.      add coph
  650.      tblr sinx
  651.      lac one,6
  652.      sub coph
  653.      sacl coph
  654.      lack sintbl
  655.      add coph
  656.      tblr cosx
  657.      lac wkph
  658.      and maskl
  659.      sacl coph
  660.      lack fines
  661.      add coph
  662.      tblr siny
  663.      lack finec
  664.      add coph
  665.      tblr cosy
  666.      zac
  667.      lt cosy
  668.      mpy sinx
  669.      lta siny
  670.      mpy cosx
  671.      apac  ; MARK
  672.      sach cosine ; store it in the cosine
  673. mult: lt mps;  now we need to do a few multiplies by sign changes due to
  674.      mpy sine ; to quadrant part of phase address
  675.      pac;     multiply sine by sine sign (:-)  and
  676.      sacl sine ;  store the result
  677.      lac modem
  678.      bgz cosm
  679.      ret
  680. cosm: mpy cosine;  now multiply cosine by the same
  681.      pac
  682.      sacl cosine ; store it
  683.      lt mpc;  load cosine differentiator from sine sign (:-)
  684.      mpy cosine;  multiply
  685.      pac
  686.      sacl cosine ; store
  687.      ret
  688.      end
  689. ;  Ebbly Ebbly Ebbly thats all folks
  690.  
  691.  
  692.